package com.sinvo.oa.controller;

import com.sinvo.oa.log.annotation.Log;
import com.sinvo.oa.log.enums.ServiceType;
import com.sinvo.oa.service.SysMenuService;
import com.sinvo.oa.exception.CustomException;
import com.sinvo.oa.result.R;
import com.sinvo.oa.result.ResultCode;
import com.sinvo.oa.entity.model.system.SysMenu;
import com.sinvo.oa.entity.vo.system.AssignMenuVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Description 菜单控制器
 */
@Api(tags = "菜单管理接口")
@RestController
@RequestMapping("admin/system/sysMenu")
public class SysMenuController {

    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 查询菜单
     * @return menuList
     * @description SysMenu.children字段存放子菜单
     */
    @PreAuthorize("hasAuthority('btn.sysMenu.list')")
    @ApiOperation(value = "菜单列表")
    @GetMapping("findNodes")
    public R findNodes(){
        List<SysMenu> menuList = sysMenuService.getAllMenuNodes();
        return R.success(menuList);
    }

    /**
     * 新增菜单
     * @param sysMenu 菜单实体类
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.INSERT)
    @PreAuthorize("hasAuthority('btn.sysMenu.add')")
    @ApiOperation(value = "新增菜单")
    @PostMapping("save")
    public R save(@Validated @RequestBody SysMenu sysMenu,BindingResult result) {
        //参数校验
        if (result.hasErrors()) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(),"非法参数");
        }
        sysMenuService.saveMenu(sysMenu);
        return R.success();
    }

    /**
     * 修改菜单
     * @param sysMenu 菜单实体类
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.UPDATE)
    @PreAuthorize("hasAuthority('btn.sysMenu.update')")
    @ApiOperation(value = "修改菜单")
    @PutMapping("update")
    public R updateById(@Validated @RequestBody SysMenu sysMenu,BindingResult result) {
        //参数校验
        if (result.hasErrors()) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(),"非法参数");
        }
        sysMenuService.updateMenu(sysMenu);
        return R.success();
    }

    /**
     * 删除菜单
     * @param id menuId
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.DELETE)
    @PreAuthorize("hasAuthority('btn.sysMenu.remove')")
    @ApiOperation(value = "删除菜单")
    @DeleteMapping("remove/{id}")
    public R remove(@PathVariable Long id) {
        //验证参数
        if (StringUtils.isEmpty(id)) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(),"非法参数");
        }
        sysMenuService.removeMenuById(id);
        return R.success();
    }

    /**
     * 改变菜单状态
     *
     * @param id     menuId
     * @param status 1/0
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.UPDATE)
    @PreAuthorize("hasAuthority('btn.sysMenu.update')")
    @ApiOperation(value = "更新菜单状态")
    @GetMapping("updateStatus/{id}/{status}")
    public R updateStatus(@PathVariable Long id, @PathVariable Integer status) {
        //验证参数 id为空或者status不等于1或0 提示错误
        if (StringUtils.isEmpty(id) || !(status == 1 || status == 0)) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(), "非法参数");
        }
        boolean success = sysMenuService.changeStatus(id, status);
        if (!success) {
            throw new CustomException(ResultCode.SERVICE_ERROR.getCode(), "修改失败，请重试");
        }
        return R.success();
    }

    /**
     * 根据角色查询菜单
     * @param roleId 角色id
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.ASSIGN)
    @PreAuthorize("hasAuthority('btn.sysRole.assignAuth')")
    @ApiOperation(value = "根据角色查询菜单")
    @GetMapping("toAssign/{roleId}")
    public R toAssign(@PathVariable Long roleId){
        //验证参数
        if (StringUtils.isEmpty(roleId)) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(),"非法参数");
        }
        List<SysMenu> menuList = sysMenuService.getMenuByRoleId(roleId);
        return R.success(menuList);
    }

    /**
     * 给角色分配菜单
     * @param assignMenuVo roleId & menuIdList
     * @return R
     */
    @Log(title = "菜单管理",businessType = ServiceType.ASSIGN)
    @PreAuthorize("hasAuthority('btn.sysRole.assignAuth')")
    @ApiOperation(value = "分配菜单")
    @PostMapping("doAssign")
    public R doAssign(@Validated @RequestBody AssignMenuVo assignMenuVo, BindingResult result){
        if (result.hasErrors()) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(),"非法参数");
        }
        boolean success = sysMenuService.doAssign(assignMenuVo);
        if (!success) {
            throw new CustomException(ResultCode.SERVICE_ERROR.getCode(), "分配失败，请重试");
        }
        return R.success();
    }
}

